#include <unistd.h>
#include <sys/ipc.h>
#include <sys/msg.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>

#include "msg.h"

#define MSG_PROJECT_ID   78
#define MSG_QUEUE_PERMS  0777

/**
** 初始化消息队列ID
**/
static
int l_sync_init(lua_State * L){
    key_t  key;
    int msgid;
    const char * msg_queue_path = luaL_checkstring(L,1);
    //Construct system msg queue
    key = ftok(msg_queue_path, MSG_PROJECT_ID);
    if(key == -1) {
        lua_pushnumber(L,-1);
        lua_pushstring(L,strerror(errno));
        return 2;
    }
    msgid = msgget(key, IPC_CREAT | MSG_QUEUE_PERMS);
    if(msgid== -1) {
        lua_pushnumber(L,-2);
        lua_pushstring(L,strerror(errno));
        return 2;
    }
    lua_pushnumber(L,msgid);
    lua_pushstring(L,"");
    return 2;
}


/**
** 往消息队列发送消息
**/
static
int l_sync_command(lua_State * L){
    //从栈底依次取参(入参的顺序)
    int msgid = luaL_checkint(L,1);
    const char * command = luaL_checkstring(L,2);  
    if(msgid <= 0){
        lua_pushboolean(L,0);
        lua_pushstring(L,"invalid msg id");
        return 2;
    }
    if(NULL==command){
        lua_pushboolean(L,0);
        lua_pushstring(L,"empty command");
        return 2;
    }
    struct sync_msg_buf msg;
    bzero(&msg,sizeof(msg));
    msg.mtype = 1;
    snprintf(msg.mtext, MSG_MAX_LEN, "%s", command);
    int ret = msgsnd(msgid , &msg, MSG_MAX_LEN, IPC_NOWAIT);
    if(ret){
        lua_pushboolean(L,0);
        lua_pushstring(L,strerror(errno));
        return 2;
    }else{
        lua_pushboolean(L,1);
        lua_pushstring(L,"");
        return 2;
    }
}


static 
const struct luaL_Reg mylibs[] = { 
    {"sync_init", l_sync_init},
    {"sync_command", l_sync_command},
    {NULL, NULL} 
}; 


int luaopen_libsyncr(lua_State* L) {
    const char* libName = "libsyncr";
    luaL_register(L,libName,mylibs);
    return 1;
}


